//
//  ViewController.swift
//  FastDevelop
//
//  Created by IOS1 on 2025/6/23.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
            super.viewDidLoad()
            
        view.backgroundColor = .yellow
        
        let calendar = SingleLineCalendar()
                calendar.delegate = self
                view.addSubview(calendar)
                
                calendar.translatesAutoresizingMaskIntoConstraints = false
                NSLayoutConstraint.activate([
                    calendar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
                    calendar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                    calendar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
                    calendar.heightAnchor.constraint(equalToConstant: 150)
                ])
        }
}

extension ViewController: SingleLineCalendarDelegate {
    func didSelectDate(_ date: Date, weekday: String, isToday: Bool) {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        
        let todayText = isToday ? "(今天)" : ""
        print("Selected date: \(formatter.string(from: date))(\(weekday))\(todayText)")
    }
}


import UIKit

protocol SingleLineCalendarDelegate: AnyObject {
    func didSelectDate(_ date: Date, weekday: String, isToday: Bool)
}

class SingleLineCalendar: UIView {
    weak var delegate: SingleLineCalendarDelegate?
    
    private var currentWeekStartDate: Date
    private var selectedDate: Date
    private let calendar = Calendar.current
    private let collectionView: UICollectionView
    private let weekLabel = UILabel()
    
    override init(frame: CGRect) {
        // 获取当前周的起始日期（周日）
        let today = Date()
        selectedDate = today
        currentWeekStartDate = today.startOfWeek()
        
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        
        super.init(frame: frame)
        
        setupViews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupViews() {
        backgroundColor = .white
        
        // 周标签（显示月份和年份）
        weekLabel.font = UIFont.systemFont(ofSize: 16, weight: .semibold)
        weekLabel.text = currentWeekStartDate.weekRangeString()
        addSubview(weekLabel)
        weekLabel.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            weekLabel.topAnchor.constraint(equalTo: topAnchor),
            weekLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
            weekLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16)
        ])
        
        // 星期标签
        let weekdaysStack = UIStackView()
        weekdaysStack.axis = .horizontal
        weekdaysStack.distribution = .fillEqually
        
        for i in 0..<7 {
            let label = UILabel()
            label.text = weekdaySymbol(for: i)
            label.font = UIFont.systemFont(ofSize: 12)
            label.textColor = .gray
            label.textAlignment = .center
            weekdaysStack.addArrangedSubview(label)
        }
        
        addSubview(weekdaysStack)
        weekdaysStack.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            weekdaysStack.topAnchor.constraint(equalTo: weekLabel.bottomAnchor, constant: 8),
            weekdaysStack.leadingAnchor.constraint(equalTo: leadingAnchor),
            weekdaysStack.trailingAnchor.constraint(equalTo: trailingAnchor)
        ])
        
        // 日期集合视图
        collectionView.register(DateCell.self, forCellWithReuseIdentifier: "DateCell")
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.backgroundColor = .clear
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.isPagingEnabled = true
        addSubview(collectionView)
        
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: weekdaysStack.bottomAnchor, constant: 8),
            collectionView.leadingAnchor.constraint(equalTo: leadingAnchor),
            collectionView.trailingAnchor.constraint(equalTo: trailingAnchor),
            collectionView.heightAnchor.constraint(equalToConstant: 60),
            collectionView.bottomAnchor.constraint(equalTo: bottomAnchor)
        ])
        
        // 初始选中今天
        DispatchQueue.main.async {
            self.selectToday()
        }
    }
    
    private func weekdaySymbol(for index: Int) -> String {
        let symbols = calendar.veryShortWeekdaySymbols
        // 调整顺序使周日排在第一位（根据中文习惯）
        let adjustedIndex = (index + calendar.firstWeekday - 1) % 7
        return symbols[adjustedIndex]
    }
    
    private func daysInWeek(for startDate: Date) -> [Date] {
        var days: [Date] = []
        var currentDate = startDate
        
        for _ in 0..<7 {
            days.append(currentDate)
            guard let nextDate = calendar.date(byAdding: .day, value: 1, to: currentDate) else {
                break
            }
            currentDate = nextDate
        }
        
        return days
    }
    
    private func dateForIndexPath(_ indexPath: IndexPath) -> Date {
        let weekOffset = indexPath.section - 1
        let startDate = calendar.date(byAdding: .weekOfYear, value: weekOffset, to: currentWeekStartDate)!
        let days = daysInWeek(for: startDate)
        return days[indexPath.item]
    }
    
    private func selectToday() {
        let today = Date()
        selectedDate = today
        
        // 找到今天在哪个section
        let todayStartOfWeek = today.startOfWeek()
        let weeksDiff = calendar.dateComponents([.weekOfYear], from: currentWeekStartDate, to: todayStartOfWeek).weekOfYear ?? 0
        let section = 1 + weeksDiff
        
        // 找到今天在周几
        let weekday = calendar.component(.weekday, from: today)
        let firstWeekday = calendar.firstWeekday
        let item = (weekday - firstWeekday + 7) % 7
        
        collectionView.reloadData()
        
        // 滚动到今天的周
        collectionView.scrollToItem(
            at: IndexPath(item: item, section: section),
            at: .centeredHorizontally,
            animated: false
        )
        
        // 更新周标签
        currentWeekStartDate = todayStartOfWeek
        weekLabel.text = currentWeekStartDate.weekRangeString()
        
        // 通知代理
        let isToday = calendar.isDateInToday(today)
        let weekdaySymbol = calendar.weekdaySymbol(from: today)
        delegate?.didSelectDate(today, weekday: weekdaySymbol, isToday: isToday)
    }
}

extension SingleLineCalendar: UICollectionViewDataSource {
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 3 // 前一周，当前周，下一周
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 7 // 一周7天
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DateCell", for: indexPath) as! DateCell
        let date = dateForIndexPath(indexPath)
        
        let day = calendar.component(.day, from: date)
        let isSelected = calendar.isDate(date, inSameDayAs: selectedDate)
        let isToday = calendar.isDateInToday(date)
        
        cell.configure(day: "\(day)", isSelected: isSelected, isToday: isToday)
        
        return cell
    }
}

extension SingleLineCalendar: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        selectedDate = dateForIndexPath(indexPath)
        collectionView.reloadData()
        
        let isToday = calendar.isDateInToday(selectedDate)
        let weekday = calendar.weekdaySymbol(from: selectedDate)
        delegate?.didSelectDate(selectedDate, weekday: weekday, isToday: isToday)
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let visibleRect = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size)
        let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
        
        if let visibleIndexPath = collectionView.indexPathForItem(at: visiblePoint) {
            let weekOffset = visibleIndexPath.section - 1
            currentWeekStartDate = calendar.date(byAdding: .weekOfYear, value: weekOffset, to: currentWeekStartDate)!
            weekLabel.text = currentWeekStartDate.weekRangeString()
            
            // 重新加载数据以确保正确的周显示
            collectionView.reloadData()
            
            // 保持选中状态
            if let selectedIndexPath = collectionView.indexPathsForSelectedItems?.first {
                selectedDate = dateForIndexPath(selectedIndexPath)
            }
        }
    }
}

extension SingleLineCalendar: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let width = collectionView.bounds.width / 7
        return CGSize(width: width, height: 60)
    }
}

// 自定义日期单元格
class DateCell: UICollectionViewCell {
    private let dayLabel = UILabel()
    private let todayIndicator = UIView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        todayIndicator.backgroundColor = .systemRed
        todayIndicator.layer.cornerRadius = 3
        todayIndicator.isHidden = true
        contentView.addSubview(todayIndicator)
        todayIndicator.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            todayIndicator.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
            todayIndicator.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -4),
            todayIndicator.widthAnchor.constraint(equalToConstant: 6),
            todayIndicator.heightAnchor.constraint(equalToConstant: 6)
        ])
        
        dayLabel.font = UIFont.systemFont(ofSize: 16)
        dayLabel.textAlignment = .center
        contentView.addSubview(dayLabel)
        dayLabel.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            dayLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
            dayLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func configure(day: String, isSelected: Bool, isToday: Bool) {
        dayLabel.text = day
        todayIndicator.isHidden = !isToday
        
        if isSelected {
            contentView.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.2)
            contentView.layer.cornerRadius = contentView.bounds.height / 2
            dayLabel.textColor = .systemBlue
            dayLabel.font = UIFont.systemFont(ofSize: 16, weight: .bold)
        } else {
            contentView.backgroundColor = .clear
            dayLabel.textColor = isToday ? .systemRed : .darkText
            dayLabel.font = UIFont.systemFont(ofSize: 16)
        }
    }
}

// Date 扩展
extension Date {
    func startOfWeek() -> Date {
        let calendar = Calendar.current
        let components = calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
        return calendar.date(from: components)!
    }
    
    func weekRangeString() -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = "MMM d"
        
        let endOfWeek = Calendar.current.date(byAdding: .day, value: 6, to: self)!
        
        let startString = formatter.string(from: self)
        let endString = formatter.string(from: endOfWeek)
        
        return "\(startString) - \(endString)"
    }
}

extension Calendar {
    func weekdaySymbol(from date: Date) -> String {
        let weekday = component(.weekday, from: date)
        return veryShortWeekdaySymbols[weekday - 1]
    }
}
